package org.spring.springboot.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spring.springboot.dao.CityDao;
import org.spring.springboot.domain.City;
import org.spring.springboot.service.CityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 城市业务逻辑实现类
 * <p>
 * Created by bysocket on 07/02/2017.
 */
@Service
public class CityServiceImpl implements CityService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class);

    @Autowired
    private CityDao cityDao;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 获取城市逻辑：
     * 如果缓存存在，从缓存中获取城市信息
     * 如果缓存不存在，从 DB 中获取城市信息，然后插入缓存
     */
    public City findCityById(Long id) {
        // 从缓存中获取城市信息
        String key = "city_" + id;
        ValueOperations<String, City> operations = redisTemplate.opsForValue();

        // 缓存存在，缓存不一定会被命中
        boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey) {
            City city = operations.get(key);

            LOGGER.info("CityServiceImpl.findCityById() : 从缓存中获取了城市 >> " + city.toString());
            return city;
        }

        // 从 DB 中获取城市信息
        City city = cityDao.findById(id);

        // 插入缓存
        operations.set(key, city, 10, TimeUnit.SECONDS);
        LOGGER.info("CityServiceImpl.findCityById() : 城市插入缓存 >> " + city.toString());

        //测试
      //添加一个 key 
        ValueOperations<String, Object> value = redisTemplate.opsForValue();
        value.set("lp", "hello word");
        //获取 这个 key 的值
        System.out.println(value.get("lp"));
        System.out.println("=============================================================================="); 
 
        //map集合
        //添加 一个 hash集合（第一种）
        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("name", "lp");
        map.put("age", "26");
        hash.putAll("entmap", map);
        //获取 map
        System.out.println(hash.entries("entmap"));
        
       System.out.println("=============================================================================="); 
        //第二种map
        Map<String,Object> map1 = new HashMap<String,Object>();
        map1.put("key1","value1");  
        map1.put("key2","value2");  
        map1.put("key3","value3");  
        map1.put("key4","value4");  
        map1.put("key5","value5");  
        redisTemplate.opsForHash().putAll("map1",map);  
        Map<String,String> resultMap= redisTemplate.opsForHash().entries("map1");  
        List<String>reslutMapList=redisTemplate.opsForHash().values("map1");  
        Set<String>resultMapSet=redisTemplate.opsForHash().keys("map1");  
        String value1=(String)redisTemplate.opsForHash().get("map1","key1");  
        System.out.println("value:"+value1);  
        System.out.println("resultMapSet:"+resultMapSet);  
        System.out.println("resultMap:"+resultMap);  
        System.out.println("resulreslutMapListtMap:"+reslutMapList);  
        System.out.println("=============================================================================="); 

        //添加 一个 list 列表
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush("lpList", "lp");
        list.rightPush("lpList", "26");
        //输出 list
        System.out.println(list.range("lpList", 0, 1));
        System.out.println("=============================================================================="); 

        //第二种list
        List<String> list1=new ArrayList<String>();  
        list1.add("a1");  
        list1.add("a2");  
        list1.add("a3");  
   
        List<String> list2=new ArrayList<String>();  
        list2.add("b1");  
        list2.add("b2");  
        list2.add("b3");  
        redisTemplate.opsForList().leftPush("listkey1",list1);  
        redisTemplate.opsForList().rightPush("listkey2",list2);  
        List<String> resultList1=(List<String>)redisTemplate.opsForList().leftPop("listkey1");  
        List<String> resultList2=(List<String>)redisTemplate.opsForList().rightPop("listkey2");  
        System.out.println("resultList1:"+resultList1);  
        System.out.println("resultList2:"+resultList2);  
        System.out.println("=============================================================================="); 

        
        
        
        
        
        
        
        
        //添加 一个 set 集合
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add("lpSet", "lp");
        set.add("lpSet", "26");
        set.add("lpSet", "178cm");
        //输出 set 集合
        System.out.println(set.members("lpSet"));
        System.out.println("=============================================================================="); 

        //添加有序的 set 集合
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add("lpZset", "lp", 0);
        zset.add("lpZset", "26", 1);
        zset.add("lpZset", "178cm", 2);
        //输出有序 set 集合
        System.out.println(zset.rangeByScore("lpZset", 0, 2));
        
        System.out.println("=============================================================================="); 

        
        
        
        
        
        
        
        
        
        
        
        return city;
    }

    @Override
    public Long saveCity(City city) {
        return cityDao.saveCity(city);
    }

    /**
     * 更新城市逻辑：
     * 如果缓存存在，删除
     * 如果缓存不存在，不操作
     */
    @Override
    public Long updateCity(City city) {
        Long ret = cityDao.updateCity(city);

        // 缓存存在，删除缓存
        String key = "city_" + city.getId();
        boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey) {
            redisTemplate.delete(key);

            LOGGER.info("CityServiceImpl.updateCity() : 从缓存中删除城市 >> " + city.toString());
        }

        return ret;
    }

    @Override
    public Long deleteCity(Long id) {

        Long ret = cityDao.deleteCity(id);

        // 缓存存在，删除缓存
        String key = "city_" + id;
        boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey) {
            redisTemplate.delete(key);

            LOGGER.info("CityServiceImpl.deleteCity() : 从缓存中删除城市 ID >> " + id);
        }
        return ret;
    }

}
